import tkinter as tk
from sklearn.linear_model import LinearRegression
from tkinter import messagebox

import numpy as np
from matplotlib import pyplot as plt


def switch_to_draw_RC(window):
    window.withdraw()  # 隐藏当前窗口
    draw_RC_window = tk.Toplevel()  # 创建新窗口
    draw_RC_window.title("绘制回归曲线")  # 界面标题
    draw_RC_window.geometry("400x500")  # 窗口大小

    # 用户输入数据
    # 创建Label对象进行提示，然后创建entry对象让用户进行输入，使用pack进行简单组件排列
    tk.Label(draw_RC_window, text="输入X值，用逗号分隔:").pack()
    x_entry = tk.Entry(draw_RC_window)
    x_entry.pack()
    tk.Label(draw_RC_window, text="输入Y值，用逗号分隔:").pack()
    y_entry = tk.Entry(draw_RC_window)
    y_entry.pack()

    # 绘制按钮
    def draw():
        try:
            # 字符串分割，然后读取并转化成float类型存进数组
            x_values = np.array([float(i) for i in x_entry.get().split(',')])
            y_values = np.array([float(i) for i in y_entry.get().split(',')])

            if len(x_values) != len(y_values):
                messagebox.showerror("错误", "X和Y值的数量必须相同")
                return

            # 创建线性回归对象
            model = LinearRegression()
            # fit方法用于根据提供的数据 x_values 和 y_values 来训练线性回归模型
            # reshape是需要传入的参数为二维数组
            model.fit(x_values.reshape(-1, 1), y_values)

            # 预测
            # 生成一个包含 100 个元素的数组，这些元素是 x_values 中最小值和最大值之间的等间距值。
            x_new = np.linspace(min(x_values), max(x_values), 100).reshape(-1, 1)
            # 用训练的model模型进行预测
            y_pred = model.predict(x_new)

            # 绘制数据点
            plt.scatter(x_values, y_values, color='blue', label='Data points')
            # 绘制回归线
            plt.plot(x_new, y_pred, color='red', linewidth=2, label='Regression line')
            plt.legend()
            plt.show()
        except ValueError:
            # 如果转化失败，则说明有错误输入
            messagebox.showerror("错误", "请输入有效的数值")

    draw_button = tk.Button(draw_RC_window, text="绘制回归曲线", command=draw)
    draw_button.pack()

    return_button = tk.Button(draw_RC_window, text="返回",
                              command=lambda: [draw_RC_window.destroy(), window.deiconify()])
    return_button.pack()
